package jmine.tec.web.front.dispatcher.request;

import java.util.List;

import jmine.tec.extensions.forms.FormHandlerHelper;
import jmine.tec.extensions.forms.FormHandler;
import jmine.tec.web.front.dao.BackOfficeRequestDAO;
import jmine.tec.web.front.dao.BackOfficeRequestStatusDAO;
import jmine.tec.web.front.dao.BaseRequestStatus;
import jmine.tec.web.front.domain.BackOfficeRequest;
import jmine.tec.web.front.forms.FormMetadataRegistry;

/**
 * Dispatcher that persists a form as a BackOfficeRequest
 * 
 * @author lundberg
 * @param <F> form type
 */
public class BackOfficeRequestFormHandler<F> implements FormHandler<F> {

    private final FormMetadataRegistry formMetadataRegistry;

    private final BackOfficeRequestStatusDAO backOfficeRequestStatusDAO;

    private final BackOfficeRequestDAO backOfficeRequestDAO;

    private final List<BackOfficeRequestFiller<F>> fillers;

    private final Class<F> formClass;

    /**
     * Constructor
     * 
     * @param formClass the class of the form
     * @param formMetadataRegistry formMetadataRegistry
     * @param backOfficeRequestStatusDAO backOfficeRequestStatusDAO
     * @param backOfficeRequestDAO backOfficeRequestDAO
     * @param fillers fillers
     */
    public BackOfficeRequestFormHandler(Class<F> formClass, FormMetadataRegistry formMetadataRegistry,
            BackOfficeRequestStatusDAO backOfficeRequestStatusDAO, BackOfficeRequestDAO backOfficeRequestDAO,
            List<BackOfficeRequestFiller<F>> fillers) {
        super();
        this.formMetadataRegistry = formMetadataRegistry;
        this.backOfficeRequestStatusDAO = backOfficeRequestStatusDAO;
        this.backOfficeRequestDAO = backOfficeRequestDAO;
        this.fillers = fillers;
        this.formClass = formClass;
    }

    /**
     * {@inheritDoc}
     */
    public void apply(F form) {
        FormHandlerHelper.validateThrowException(form, this);
        BackOfficeRequest request = this.backOfficeRequestDAO.createBean();
        for (BackOfficeRequestFiller<F> filler : this.fillers) {
            filler.fill(request, form);
        }
        this.formMetadataRegistry.find(form).getCustomFiller().fill(request, form);
        request.setStatus(this.backOfficeRequestStatusDAO.findBySystemIdentifier(BaseRequestStatus.PENDING));
        this.backOfficeRequestDAO.save(request);
    }

    /**
     * {@inheritDoc}
     */
    public List<String> validate(F form) {
        return this.formMetadataRegistry.find(form).getFormHandler().validate(form);
    }

    /**
     * {@inheritDoc}
     */
    public Class<F> formClass() {
        return this.formClass;
    }
}